﻿using System;
using System.Collections.Generic;
using System.DirectoryServices.ActiveDirectory;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;

namespace SuperKit {
  /// <summary>
  /// Interaction logic for MainWindow.xaml
  /// </summary>
  public partial class MainWindow : Window, IExecutorOwner {
    private string _argText;
    public string FileTarget { get; set; }

    public MainWindow() {
      InitializeComponent();
    }

    private void BrowseDialog_Click(object sender, RoutedEventArgs e) {
      FolderBrowser.FolderBrowserDialog dlg = new FolderBrowser.FolderBrowserDialog();
      if (dlg.ShowDialog() == true) {
        txtDirectory.Text = dlg.SelectedFolder;
      }
    }

    private void Settings_Click(object sender, RoutedEventArgs e) {
      SettingsWindow dlg = new SettingsWindow();
      dlg.ShowDialog();
    }

    private void Rename_Click(object sender, RoutedEventArgs e) {
      BatchRename dlg = new BatchRename();
      dlg.Add(new DirectoryInfo(txtDirectory.Text));
      dlg.Show();
    }

    private void OnLoaded(object sender, RoutedEventArgs e) {
      InitMaxThread();
      InitShortCut();

      var directory = ArgReader.InitialArgs.Directory;
      // 如果指定了FileTarget，则使用FileTarget替换
      if (Kit.IsEmpty(FileTarget) == false) {
        directory = FileTarget;
      }

      Root = directory;
      CommandReader.Inst.ToString();
      txtDirectory.Text = directory;
      CommandReader.Inst.Fill(tree_Command);
      SetupDirectory(directory);
      SetCommandLayer();
      SetDefaultCommand();

    }


    private delegate void TxtHandeler(object obj);
    private delegate void LogHandeler(int index, object obj);
    private delegate void CloseHandler();
    private const int MAX_THREAD = 10;
    public int MaxShellCount => Math.Max(1, Cfg.MaxShellCount);
    private ConfigReader Cfg => ConfigReader.Instance;
    public string Root { get; private set; }


    public void ToTitle(string format, params object[] args) {
      Dispatcher.Invoke(() => {
        Title = SafeFormat(format, args);
      });
    }



    private string SafeFormat(string format, params object[] args) {
      string text = "";
      try {
        text = string.Format(format, args);
      } catch (Exception) {
        text = format;
      }
      return text;
    }




    private void InitShortCut() {
      foreach (var i in CommandReader.Inst.Items) {
        if (i.IsShortCut) {
          MenuItem item = new MenuItem();
          item.Header = i.Name;
          item.Tag = i;
          item.Click += OnFastAction;
          menu_FastOperation.Items.Add(item);
        }
      }
    }

    private void OnFastAction(object sender, EventArgs e) {
      MenuItem item = sender as MenuItem;
      CommandReader.Item cmd = item.Tag as CommandReader.Item;
      txtArgs.Text = cmd.Command;
      Execute();
    }


    private void InitMaxThread() {
      menu_Thread.Items.Clear();

      var current = MaxShellCount;
      for (int i = 0; i < MAX_THREAD; i++) {
        MenuItem item = new MenuItem();
        item.Header = $"{i + 1}线程";
        item.Tag = i;
        if (i + 1 == current) {
          item.Icon = App.GetCheckImage();
        }
        item.Click += ThreadItem_Click;
        menu_Thread.Items.Add(item);
      }
      label_ExecuteShell.Text = $"多线程执行:{current}";
    }

    private void ThreadItem_Click(object sender, RoutedEventArgs e) {
      MenuItem item = (MenuItem)sender;
      int index = (int)item.Tag;
      Cfg.MaxShellCount = index + 1;
      Cfg.Save();
      InitMaxThread();
    }



    private void SetupDirectory(string directory) {
      DirectoryReader.Inst.SetDirectory(directory);
      DirectoryReader.Inst.Fill(listDirectory);
    }

    public void StartUdpServer() {
      CogUdpServer.Instance.Start();
      CogUdpServer.Instance.Processor = MessageProcessor;
    }

    private void MessageProcessor(string ip, string msg) {
      var splits = msg.Split('|');
      var idx = int.Parse(splits[0]);
      Log(idx, splits[1]);
    }

    private void SetDefaultCommand() {
      txtArgs.Text = Cfg.LastArgs;
    }

    private void SetCommandLayer() {
      RecoverWindow();
    }

    public void RefreshLog() {
      listLog.Items.Clear();
      for (int i = 0; i < MaxShellCount; i++) {
        listLog.Items.Add("待命");
      }
    }

    public void CloseForm() {
      Dispatcher.Invoke(() => {
        this.Close();
      });
    }


    private void Execute() {
      var arg = new ArgReader(txtArgs.Text, txtDirectory.Text);
      arg.Execute(this);
    }

    public bool UseShell { get; set; } = false;


    private void tsRecover_Click(object sender, EventArgs e) {
      RecoverWindow();
    }

    private void HideWindow() {
      this.Opacity = 0;
      this.Hide();
    }

    private void RecoverWindow() {
      this.Opacity = 1;
      this.Show();
    }


    private const string TEST_TEXT = "-test";
    private void btnSwitchTest_Click(object sender, EventArgs e) {

      if (txtArgs.Text.IndexOf(TEST_TEXT) != -1) {
        txtArgs.Text = txtArgs.Text.Replace(TEST_TEXT, "").Replace("  ", " ");
      } else {
        txtArgs.Text = (txtArgs.Text + " -test").Replace("  ", " ");
      }
    }



    public int GetMaxShellCount() {
      return MaxShellCount;
    }

    public bool IsUseShell() {
      return UseShell;
    }


    public void Flush(string str) {
      Dispatcher.Invoke(() => {
        txtConsole.AppendText(str);
        txtConsole.AppendText("\r\n");
      });
    }


    public void Status(string str) {
      Dispatcher.Invoke(() => {
        labelStatus.Content = str;
      });
    }


    public void Error(string str) {
      Flush(str);
    }

    void IExecutorOwner.Title(string str) {
      Dispatcher.Invoke(() => {
        Title = str;
      });
    }

    public void Log(int index, string str) {
      Dispatcher.Invoke(() => {
        if (index < 0 || index >= listLog.Items.Count) {
          listLog.Items.Add(str);
        } else {
          listLog.Items[index] = str;
        }
      });
    }

    public string GetArgText() {
      return _argText;
    }

    private void Exit_Click(object sender, RoutedEventArgs e) {
      Close();
    }

    void PrintNonEmptyLines(string input) {
      // 使用StringReader逐行读取字符串
      using (StringReader reader = new StringReader(input)) {
        string line;
        while ((line = reader.ReadLine()) != null) {
          // Trim前后空格/制表符
          line = line.Trim();

          // 跳过空行
          if (line.Length > 0) {
            Flush(line);
          }
        }
      }
    }

    private void tree_Command_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e) {
      var item = tree_Command.SelectedItem as TreeViewItem;
      if (item == null) {
        return;
      }

      var command = item.DataContext as CommandReader.Item;
      if (command != null) {
        txtArgs.Text = command.Command;
        PrintNonEmptyLines(command.Description);
        Cfg.LastCommand = command.Name;
      }
    }

    private void Execute_Click(object sender, RoutedEventArgs e) {
      Execute();
    }

    private void ExecuteDirectory_Click(object sender, RoutedEventArgs e) {
      _argText = txtArgs.Text;
      DirectoryExecutor de = new(txtDirectory.Text, this);
      de.ExecuteSub();
    }

    private void ExecuteShell_Click(object sender, RoutedEventArgs e) {
      UseShell = true;
      ExecuteDirectory_Click(sender, e);
    }

    private void Window_Closed(object sender, EventArgs e) {
      if (CogUdpServer.IsActive) {
        CogUdpServer.Instance.Close();
      }
    }


    private void GalleryWindow_Click(object sender, RoutedEventArgs e) {
      var dlg = new GalleryWindow();
      dlg.DirPath = txtDirectory.Text;
      dlg.Show();
    }

    private void VideoWindow_Click(object sender, RoutedEventArgs e) {
      var dlg = new SuperPlayer();
      dlg.DirPath = txtDirectory.Text;
      dlg.Show();
    }


    private void HtmlWindow_Click(object sender, RoutedEventArgs e) {
      var win = new HtmlWindow();
      win.Show();
    }

    private void SwitchDirectory_Click(object sender, MouseButtonEventArgs e) {
      DirectoryReaderItem item = listDirectory.SelectedItem as DirectoryReaderItem;
      if (item == null) {
        return;
      }
      txtDirectory.Text = item.FullPath;
    }

    private void RcWindow_Click(object sender, RoutedEventArgs e) {

    }
  }
}
